/*
 * SemanticNodeMethodStatement.h
 *
 *  Created on: 03.11.2009.
 *      Author: hrvoje
 */

#ifndef SEMANTICNODEMETHODSTATEMENT_H_
#define SEMANTICNODEMETHODSTATEMENT_H_

#include "SemanticNode.h"

#include "../main_container.h"

#include <string>
#include <sstream>
#include <vector>

extern MainContainer *compilerData;

class SemanticNodeExpression;
class SemanticNodeVariableName;
class SemanticNodeMethodBody;

class SemanticNodeVariableDefinition : public SemanticNode, public ValueType {
private:
	bool traceDiscrete;
	bool traceContinuous;

	std::string name;
	SemanticNodeExpression *initExpression;

	SemanticNodeVariableDefinition(const SyntaxTreeNode *tracePart, const SyntaxTreeNode *varType, const SyntaxTreeNode *varName, SemanticNode *parent);

	void setInitExpression(SemanticNodeExpression *nodeExpression);

public:
	~SemanticNodeVariableDefinition();
	virtual std::string toDebugString(int tab);

	std::string getName();
	bool isInitialized();
	static std::vector<SemanticNodeVariableDefinition *> analyzeNodeVariableDefinition(const SyntaxTreeNode *fieldNode, SemanticNode *parent);

};

class SemanticNodeAssignment : public SemanticNode {
private:
	SemanticNodeVariableName *variableValue;
	SemanticNodeExpression *expression;
public:
	SemanticNodeAssignment(const SyntaxTreeNode *syntaxNode, SemanticNode *parent);
	~SemanticNodeAssignment();
	virtual std::string toDebugString(int tab);
};

class SemanticNodeMethodCall : public SemanticNode, public ValueType {
private:
	std::string name;
	std::vector<SemanticNodeExpression *> arguments;
	SemanticNodeVariableName *variableValue;
	bool instanceCall;

public:
	SemanticNodeMethodCall(const SyntaxTreeNode *methodCallNode, SemanticNode *parent);
	bool isInstanceMethodCall();
	virtual std::string toDebugString(int tab);
};


class SemanticNodeIfStatement : public SemanticNode {
private:
	SemanticNodeExpression *expression;
	SemanticNodeMethodBody *ifPart;
	SemanticNodeMethodBody *elsePart;

public:
	SemanticNodeIfStatement(const SyntaxTreeNode *syntaxNode, SemanticNode *parent);
	~SemanticNodeIfStatement();
	virtual std::string toDebugString(int tab);
};

class SemanticNodeWhileStatement : public SemanticNode {
private:
	SemanticNodeExpression *expression;
	SemanticNodeMethodBody *body;
	bool isDoWhile;
public:
	SemanticNodeWhileStatement(const SyntaxTreeNode *syntaxNode, SemanticNode *parent);
	~SemanticNodeWhileStatement();
	virtual std::string toDebugString(int tab);
};

class SemanticNodeForStatement : public SemanticNode {
private:
	std::vector<SemanticNodeVariableDefinition *> startVariables;
	SemanticNode *startStatement;
	SemanticNodeExpression *expression;
	SemanticNode *countStatement;
	std::vector<SemanticNodeVariableDefinition *> countVariables;
	SemanticNodeMethodBody *body;
public:
	SemanticNodeForStatement(const SyntaxTreeNode *syntaxNode, SemanticNode *parent);
	~SemanticNodeForStatement();
	virtual std::string toDebugString(int tab);
};

class SemanticNodeSwitchCaseStatement : public SemanticNode {
private:
	SemanticNodeExpression * expression;
	std::vector<SemanticNodeExpression *> caseExpressions;
	std::vector<SemanticNodeMethodBody *> caseBodies;
	SemanticNodeMethodBody *defaultBody;


public:
	SemanticNodeSwitchCaseStatement(const SyntaxTreeNode *syntaxNode, SemanticNode *parent);
	~SemanticNodeSwitchCaseStatement();
	virtual std::string toDebugString(int tab);
};

class SemanticNodeBreakStatement : public SemanticNode {
private:

public:
	SemanticNodeBreakStatement(const SyntaxTreeNode *syntaxNode, SemanticNode *parent);
	~SemanticNodeBreakStatement();
	virtual std::string toDebugString(int tab);
};

class SemanticNodeContinueStatement : public SemanticNode {
private:

public:
	SemanticNodeContinueStatement(const SyntaxTreeNode *syntaxNode, SemanticNode *parent);
	~SemanticNodeContinueStatement();
	virtual std::string toDebugString(int tab);
};

class SemanticNodeReturnStatement : public SemanticNode {
private:
	SemanticNodeExpression *expression;
public:
	SemanticNodeReturnStatement(const SyntaxTreeNode *syntaxNode, SemanticNode *parent);
	~SemanticNodeReturnStatement();
	virtual std::string toDebugString(int tab);
};

class SemanticNodeGotoStatement : public SemanticNode {
private:
	std::string name;
public:
	SemanticNodeGotoStatement(const SyntaxTreeNode *syntaxNode, SemanticNode *parent);
	~SemanticNodeGotoStatement();
	virtual std::string toDebugString(int tab);
};

class SemanticNodeStartStatement : public SemanticNode {
private:
	std::string name;
	std::vector<SemanticNodeExpression *> arguments;
	std::vector<std::string> startAssignmentNames;
	std::vector<SemanticNodeExpression *> startAssignmentExpressions;
	void analyzeStartAssignment(SyntaxTreeNode *syntaxNode);
public:
	SemanticNodeStartStatement(const SyntaxTreeNode *syntaxNode, SemanticNode *parent);
	~SemanticNodeStartStatement();
	virtual std::string toDebugString(int tab);
};

class SemanticNodeStopStatement : public SemanticNode {
private:
	std::string name;
public:
	SemanticNodeStopStatement(const SyntaxTreeNode *syntaxNode, SemanticNode *parent);
	~SemanticNodeStopStatement();
	virtual std::string toDebugString(int tab);
};

#endif /* SEMANTICNODEMETHODSTATEMENT_H_ */
